﻿namespace MailChimp.Types

open System
open System.Text

//==================================================================================
//  Webhooks
//==================================================================================

module Webhooks =

    /// <summary>Webhook type enum.</summary>
    type WebhookType =
        | Subscribe = 0
        | Unsubscribe = 1
        | Profile = 2
        | UpEmail = 3
        | Cleaned = 4
        | Campaign = 5

    //------------------------------------------------------------------------------
    //  (*) CLI compatible event args
    //------------------------------------------------------------------------------

    /// <summary>CLI compatible webhooks event args.</summary>
    type WebhooksEventArgs =
        inherit EventArgs
        new : typ:WebhookType * timestamp:DateTime * data:NestedDict * reqData:string -> WebhooksEventArgs

        /// <summary>Gets the type of the event.</summary>
        member Type : WebhookType

        /// <summary>Gets the timestamp of the event.</summary>
        member Timestamp : DateTime

        /// <summary>Gets the parsed request data.</summary>
        member Data : NestedDict

        /// <summary>Gets the raw request data.</summary>
        member RequestData : string

    type WebhooksEventHandler = delegate of obj * WebhooksEventArgs -> unit
    type ErrorEventHandler = delegate of obj * string -> unit


namespace MailChimp

open System
open System.Net
open System.Threading
open MailChimp.Types.Webhooks

//==================================================================================
//  Webhooks Listener
//==================================================================================

[<Sealed>]
/// <summary>Webhooks listener. A server that listens for POST request from MailChimp.
/// <para>If the server receives a valid request from MailChimp the received data is
/// parsed and an event, which can be handled in a custom application, is emitted.</para></summary>
/// <remarks>Implements <see cref="System.Net.HttpListener"/>.
/// <para>Incoming requests are processed asynchronously.</para></remarks>
type WebhooksListener =
    interface IDisposable

    new : unit -> WebhooksListener

    /// <summary>Gets or sets the secret key, which is added to the Webhook URL querystring.
    /// <para>Example: http://{host}/{path}/?key={key}</para></summary>
    /// <example>http://{host}/{path}/?key={key}</example>
    member Key : string with get, set

    /// <summary>Gets the Uniform Resource Identifier (URI) prefixes
    /// handled by this Listener object.</summary>
    member Prefixes : HttpListenerPrefixCollection

    /// <summary>Gets a value that indicates whether Listener has been started.</summary>
    member IsListening : bool

    /// <summary>Gets or sets a Boolean value that specifies whether your application receives
    /// exceptions that occur when an Listener sends the response to the client.
    /// <para>Default is false.</para></summary>
    member IgnoreWriteExceptions : bool with get, set

    /// <summary>Allows this instance to receive incoming requests asynchronously.</summary>
    member Start : unit -> unit

    /// <summary>Causes this instance to stop receiving incoming requests.</summary>
    member Stop : unit -> unit

    /// <summary>Shuts down the Listener object immediately,
    /// discarding all currently queued requests.</summary>
    member Abort : unit -> unit

    /// <summary>Shuts down the Listener object.</summary>
    member Close : unit -> unit

    [<CLIEvent>]
    /// <summary>Occurs when valid webhook is received.</summary>
    member WebhookReceived : IEvent<WebhooksEventHandler, WebhooksEventArgs>

    [<CLIEvent>]
    /// <summary>Occurs when invalid request is received.</summary>
    member InvalidRequest : IEvent<ErrorEventHandler, string>